package cn.zhou.system.service.impl;

import cn.zhou.basic.anno.PreAuthorize;
import cn.zhou.basic.util.Classutil;
import cn.zhou.system.domain.Permission;
import cn.zhou.system.mapper.PermissionMapper;
import cn.zhou.system.service.IPermissionScanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
@Service
public class PermissionScanServiceImpl implements IPermissionScanService {

    private static final String  PKG_PREFIX   = "cn.zhou.";
    private static final String  PKG_SUFFIX   = ".controller";



        @Autowired
        private PermissionMapper permissionMapper;
        @Override
        public void scanPermission() {
            //获取org.yaosang下面所有的模块目录
            String path = this.getClass().getResource("/").getPath() + "/cn/zhou/";
            File file = new File(path);
            File[] files = file.listFiles(new FileFilter() {
                @Override
                public boolean accept(File file) {
                    return file.isDirectory();
                }
            });

            //获取org.yaosang.*.web.controller里面所有的类
            Set<Class> clazzes = new HashSet<>();
            for (File fileTmp : files) {
                System.out.println(fileTmp.getName());
                clazzes.addAll(Classutil.getClasses(PKG_PREFIX+fileTmp.getName()+PKG_SUFFIX));
            }

            for (Class clazz : clazzes) {
                Method[] methods = clazz.getMethods();
                if (methods==null || methods.length<1)
                    return;
                for (Method method : methods) {
                    String uri = getUri(clazz, method);
                    try {
                        PreAuthorize preAuthorizeAnno = method.getAnnotation(PreAuthorize.class);
                        if (preAuthorizeAnno==null)
                            continue;
                        String name = preAuthorizeAnno.name();
                        String permissionSn = preAuthorizeAnno.value();
                        Permission permissionTmp = permissionMapper.loadBySn(permissionSn);
                        //如果不存在就添加
                        if (permissionTmp == null) {
                            Permission permission = new Permission();
                            permission.setName(name);
                            permission.setSn(permissionSn);
                            permission.setUrl(uri);
                            permissionMapper.add(permission);
                        }else{
                            //如果不存在就修改
                            permissionTmp.setName(name);
                            permissionTmp.setSn(permissionSn);
                            permissionTmp.setUrl(uri);
                            permissionMapper.update(permissionTmp);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        private String getUri(Class clazz, Method method) {
            String classPath = "";
            Annotation annotation = clazz.getAnnotation(RequestMapping.class);
            if (annotation!=null){
                RequestMapping requestMapping = (RequestMapping) annotation;
                String[] values = requestMapping.value();
                if(values!=null&&values.length>0){
                    classPath = values[0];
                    if (!"".equals(classPath)&&!classPath.startsWith("/"))
                        classPath="/"+classPath;
                }
            }
            GetMapping getMapping =  method.getAnnotation(GetMapping.class);
            String methodPath = "";
            if (getMapping!=null){
                String[] values = getMapping.value();
                if(values!=null&&values.length>0){
                    methodPath = values[0];
                    if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                        methodPath="/"+methodPath;
                }
            }
            PostMapping postMapping =  method.getAnnotation(PostMapping.class);
            if (postMapping!=null){
                String[] values = postMapping.value();
                if(values!=null&&values.length>0){
                    methodPath = values[0];
                    if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                        methodPath="/"+methodPath;
                }
            }
            DeleteMapping deleteMapping =  method.getAnnotation(DeleteMapping.class);
            if (deleteMapping!=null){
                String[] values = deleteMapping.value();
                if(values!=null&&values.length>0){
                    methodPath = values[0];
                    if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                        methodPath="/"+methodPath;
                }
            }
            PutMapping putMapping =  method.getAnnotation(PutMapping.class);
            if (putMapping!=null){
                String[] values = putMapping.value();
                if(values!=null&&values.length>0){
                    methodPath = values[0];
                    if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                        methodPath="/"+methodPath;
                }

            }
            PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
            if (patchMapping!=null){
                String[] values = patchMapping.value();
                if(values!=null&&values.length>0){
                    methodPath = values[0];
                    if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                        methodPath="/"+methodPath;
                }
            }
            RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
            if (requestMapping!=null){
                String[] values = requestMapping.value();
                if(values!=null&&values.length>0){
                    methodPath = values[0];
                    if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                        methodPath="/"+methodPath;
                }
            }
            return classPath+methodPath;
        }
}
